﻿using System;
using System.Collections.Generic;
using System.Text;
using Irony.Parsing;
using System.Collections;
using System.IO;

namespace Practica1_Compi2
{
    class Analizador
    {
        public String cad="";
        public StringBuilder thtml;
        public List<string> nums;
        public List<string> cads;
        public int[] numsord;
        public string[] cadsord;
        public StringBuilder graph;
        int nivel = 0;

        public bool isValid(string codigo,Grammar grammar) {
            LanguageData lenguaje = new LanguageData(grammar);
            Parser p = new Parser(lenguaje);
            ParseTree arbol = p.Parse(codigo);
           
            nums = new List<string>();
            cads = new List<string>();
            
                recursivo(arbol.Root.ChildNodes);
                dibujar(arbol.Root.ChildNodes, arbol.Root);
            
                return arbol.Root != null;
        }

        public void recursivo(ParseTreeNodeList nodo)
        {

            if (nodo != null && nodo.Count > 0)
            {
                ParseTreeNodeList nodoaux = nodo;
                foreach (ParseTreeNode hijo2 in nodoaux)
                {
                 //   print(hijo2);
                    String a = hijo2.Term.ToString();
                    if (a.CompareTo("Number") == 0){
                        nums.Add(hijo2.FindTokenAndGetText());
                    }
                    else if (a.CompareTo("cade") == 0) {
                        cads.Add(hijo2.FindTokenAndGetText());
                    }
                    recursivo(hijo2.ChildNodes);
                }

            }
        }
        public void dibujar(ParseTreeNodeList roo, ParseTreeNode a) {
            graph = new StringBuilder();
            graph.Append("digraph G {\n");
            dibujarNodo(roo,0);
            graph.Append("}");

            var archivo = "C:\\folder\\graph.dot";

            // eliminar el fichero si ya existe
            if (File.Exists(archivo))
                File.Delete(archivo);

            // crear el fichero
            using (var fileStream = File.Create(archivo))
            {
                var texto = new UTF8Encoding(true).GetBytes(graph.ToString());
                fileStream.Write(texto, 0, texto.Length);
                fileStream.Flush();
            } System.Diagnostics.Process.Start("C:/folder/graph.bat");
            
        }

        public void dibujarNodo(ParseTreeNodeList nodo, int idpadre)
        {
            if (nodo != null && nodo.Count > 0)
            {
                ParseTreeNodeList nodoaux = nodo;
                foreach (ParseTreeNode hijo2 in nodoaux)
                {
                    nivel++;
                    graph.Append(nivel + "[label=\"" + pr(hijo2) + "\"];\n");
                    graph.Append(idpadre + "->" + nivel + "; \n");
                    dibujarNodo(hijo2.ChildNodes, nivel);

                }
            }
        }

        public String pr(ParseTreeNode node)
        {
            String cadena = node.ToString();
            int index = cadena.IndexOf("(");
            cadena = cadena.Substring(0, (index < 0) ? cadena.Length : index);
           return cadena;
        }

        public string traductorhtml() {
            thtml = new StringBuilder();
            Hashtable hashcad=null;
            Hashtable hashnum=null;
            if (nums != null)
            {
               hashnum = new Hashtable();
                foreach (string prime in nums) // Loop through List with foreach
                {
                    int a = verificarhash(hashnum, prime);
                    if (a == 0)
                    {
                        hashnum.Add(prime, 1);
                        
                    }
                    else {
                       int val =(int) hashnum[prime];
                       string k = prime;
                       val++;
                       hashnum.Remove(prime);
                       hashnum.Add(k, val);
                    }
                }
            }
            if (cads != null)
            {
               hashcad = new Hashtable();
                foreach (string prime in cads) // Loop through List with foreach
                {
                    int a = verificarhash(hashcad, prime);
                    if (a == 0)
                    {
                        hashcad.Add(prime, 1);
                    }
                    else
                    {
                        int val = (int)hashcad[prime];
                        string k = prime;
                        val++;
                        hashcad.Remove(prime);
                        hashcad.Add(k, val);
                    }
                }
            }
            thtml.Append("");
            thtml.Append("<html>\n <h1>Total de numero: ");
            thtml.Append(nums.Count);
            thtml.Append("</h1>\n <p>numeros repetidos:\n <table border=1>\n <tr>\n <td>numero</td>\n <td>cantidad</td>\n </tr>\n");
            if (hashnum!=null)
            {
                numsord = new int[hashnum.Count];
                int conteo=0;
                foreach (string value in hashnum.Keys)
                {
                     int value2 = (int)hashnum[value];
                     int nu = Convert.ToInt32(value);
                     numsord[conteo] = nu;
                     conteo++;
                    if (value2 > 1) {
                        thtml.Append("<tr>\n <td>");
                        thtml.Append(value);
                        thtml.Append("</td>\n <td>");
                        thtml.Append(value2);
                        thtml.Append(" veces </td>\n </tr>\n");
                    }
                }
                Burbujanum(numsord);
            }
            thtml.Append("</table>\n <br>Listado ordenado ascendente\n ");
            if(numsord!=null){
                thtml.Append("<br>");
            for (int i = 0; i < numsord.Length; i++) {
                thtml.Append(numsord[i]+",");
            }
            }
            thtml.Append("<br>\n <br>Listado ordenado descendente\n ");
            if (numsord != null)
            {
                thtml.Append("<br>");
                for (int m=numsord.Length; m>0 ; m--)
                {
                    thtml.Append(numsord[m-1] + ",");
                }
            }
            thtml.Append("</p>\n");
            thtml.Append("<html>\n <h1>Total de palabras: ");
            thtml.Append(cads.Count);
            thtml.Append("</h1>\n <p>palabras repetidas:\n <table border=1>\n <tr>\n <td>palabra</td>\n <td>cantidad</td>\n </tr>\n");
            if (hashcad != null)
            {
                cadsord = new string[hashcad.Count];
                int conteo = 0;
                foreach (string value in hashcad.Keys)
                {
                    int value2 = (int)hashcad[value];
                    cadsord[conteo] = value;
                    conteo++;
                    if (value2 > 1)
                    {
                        thtml.Append("<tr>\n <td>");
                        thtml.Append(value);
                        thtml.Append("</td>\n <td>");
                        thtml.Append(value2);
                        thtml.Append(" veces </td>\n </tr>\n");
                    }
                }
                Burbujacad(cadsord);
            }
            thtml.Append("</table>\n <br>\n <table border=1>\n <tr>\n <td>Palabras en orden ascendente</td>\n  <td>Palabras en orden descendente</td>\n </tr>\n <tr>\n ");
       
            if (cadsord != null)
            {
                thtml.Append("<td>\n");
                for (int i = 0; i < cadsord.Length; i++)
                {
                    thtml.Append(cadsord[i] + "<br>\n");
                }
        
                thtml.Append("</td>\n <td>\n");
                for (int m = cadsord.Length; m > 0; m--)
                {
                    thtml.Append(cadsord[m - 1] + "<br>\n");
                }
                thtml.Append("</td>\n");
            }
            thtml.Append("</tr>\n </table>\n </p>\n");
            thtml.Append("<h1>Arbol de derivacion</h1>\n <img src=\"C:\\folder\\graph.png");
            thtml.Append("\">\n </html>");
            
            return thtml.ToString();
        }

        public int verificarhash(Hashtable a, string b) {
            if (a.Count != 0) {
                foreach (string key in a.Keys)
                {
                    if (key.CompareTo(b) == 0) {
                        return 1;
                    }
                }
            }
            return 0;
        }

        public void Burbujanum(int[] l) { 
            int i, j; 
            int temp;
            for (i = 0; i < l.Length; i++) 
            { 
                for (j = 0; j < l.Length-1; j++) { 

               if (l[j] > l[j + 1]) { 
                   temp = l[j]; 
                   l[j] = l[j + 1]; 
                   l[j + 1] = temp; 
                     } 
                  } 
             } 
            }

        public void Burbujacad(string[] l)
        {
            int i, j;
            string temp;
            for (i = 0; i < l.Length; i++)
            {
                for (j = 0; j < l.Length - 1; j++)
                {

                    if (l[j].CompareTo(l[j + 1])>0)
                    {
                        temp = l[j];
                        l[j] = l[j + 1];
                        l[j + 1] = temp;
                    }
                }
            }
        } 

        public ParseTreeNode getRoot(string codigo, Grammar grammar) {
            LanguageData lenguaje = new LanguageData(grammar);
            Parser p = new Parser(lenguaje);
            ParseTree arbol = p.Parse(codigo);
            return arbol.Root;
        }
    }

    }

